package com.lagou.web;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;

import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;

/**
 * @author: wudong
 * @create: 2021-07-16 17:10
 **/
public class SpringApplication {
    public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol";
    public static final String START_CLASS = "servlet.start.class";


    private Class primarySources;

    private String protocol = DEFAULT_PROTOCOL;

    public SpringApplication(Class primarySources) {
        this.primarySources = primarySources;
    }

    public static void run(Class<?> primarySource) {
        new SpringApplication(primarySource).run();
    }

    public void run(){
        try {
            //实例化一个Tomcat
            Tomcat tomcat = new Tomcat();
            int port = 8080;
            File baseDir = createTempDir("tomcat",port);
            //设置Tomcat的工作临时目录
            tomcat.setBaseDir(baseDir.getAbsolutePath());
            Context context = tomcat.addWebapp("/", "/data/");
            //设置主启动类
            ServletContext servletContext = context.getServletContext();
            servletContext.setAttribute(START_CLASS,this.primarySources);

            //默认使用Http11NioProtocal实例化Connector
            Connector connector = new Connector(this.protocol);
            //给Service添加Connector
            tomcat.getService().addConnector(connector);
            connector.setPort(port);
            tomcat.setConnector(connector);
            //关闭热部署
            tomcat.getHost().setAutoDeploy(false);
            tomcat.start();
            startDaemonAwaitThread(tomcat);
        } catch (Exception e) {
            throw new RuntimeException("tomcat failed to start",e);
        }
    }


    protected final File createTempDir(String prefix,int port) {
        try {
            File tempDir = File.createTempFile(prefix + ".", "." + port);
            tempDir.delete();
            tempDir.mkdir();
            tempDir.deleteOnExit();
            return tempDir;
        }
        catch (IOException ex) {
            throw new RuntimeException(
                    "Unable to create tempDir. java.io.tmpdir is set to " + System.getProperty("java.io.tmpdir"), ex);
        }
    }


    private void startDaemonAwaitThread(final Tomcat tomcats) {
        Thread awaitThread = new Thread("container") {

            @Override
            public void run() {
                tomcats.getServer().await();
            }

        };
        awaitThread.setContextClassLoader(getClass().getClassLoader());
        awaitThread.setDaemon(false);
        awaitThread.start();
    }
}
